/**
 * @fileoverview Form 表单容器组件 - Formily Shadcn 版本
 * 
 * 这是 formily-shadcn 项目中的核心表单容器组件。
 * 该组件是整个表单系统的基础，提供：
 * 1. Formily 表单状态管理集成
 * 2. 多种布局模式支持（垂直、水平、内联）
 * 3. 设计器拖拽行为定义
 * 4. 国际化支持
 * 5. 响应式布局
 * 
 * 设计理念：
 * - 作为所有表单字段的容器和上下文提供者
 * - 提供灵活的布局选项以适应不同的 UI 需求
 * - 与 Formily 生态系统完全集成
 * - 支持设计器环境下的可视化编辑
 * 
 * 对比 formily-antd-v5:
 * - 使用 Tailwind CSS 替代 Ant Design 的样式系统
 * - 保持了相同的 Formily 集成模式
 * - 提供了更现代的默认样式
 */

import React, { useMemo } from 'react'
import { createBehavior, createResource } from '@bill_law6/designable-core'
import { createForm } from '@formily/core'
import { observer, FormProvider } from '@formily/react'
import { usePrefix, DnFC } from '@bill_law6/designable-react'
import { AllSchemas } from '../../schemas'
import { AllLocales } from '../../locales'
import { cn } from '../../lib/utils'

/**
 * Form 组件的 Props 接口定义
 * 
 * 继承了原生 HTML form 元素的所有属性，并扩展了表单特有的配置
 */
export interface FormProps extends React.HTMLAttributes<HTMLFormElement> {
  /** Formily 表单实例，如果不提供会自动创建 */
  form?: any
  /** 表单布局模式 */
  layout?: 'vertical' | 'horizontal' | 'inline'
}

/**
 * Form 组件实现
 * 
 * 这是一个使用 Formily 观察者模式的表单容器组件。
 * 主要功能：
 * 1. 表单实例管理 - 创建或接收表单实例
 * 2. 布局控制 - 根据 layout 属性应用不同的 CSS 布局
 * 3. 上下文提供 - 通过 FormProvider 为子组件提供表单上下文
 * 4. 样式集成 - 使用 Tailwind CSS 实现响应式布局
 */
export const Form: DnFC<FormProps> = observer((props) => {
  const { className, form: formProp, layout = 'vertical', children, ...rest } = props
  // 使用 Designable 的前缀系统，确保样式命名空间
  const prefix = usePrefix('designable-form')
  
  /**
   * 表单实例创建和管理
   * 
   * 使用 useMemo 优化性能，只在 formProp 变化时重新创建表单。
   * 如果外部传入了表单实例则使用外部的，否则创建新的设计器表单实例。
   */
  const form = useMemo(
    () =>
      formProp ||
      createForm({
        designable: true, // 标记为设计器模式，启用特殊行为
      }),
    [formProp]
  )

  return (
    <FormProvider form={form}>
      <form
        {...rest}
        className={cn(
          prefix, // Designable 前缀类
          {
            // 垂直布局 - 字段垂直排列，适合大多数表单场景
            'space-y-4': layout === 'vertical',
            'flex flex-col gap-4': layout === 'vertical',
            // 水平布局 - 字段水平排列并可换行，适合复杂表单
            'flex flex-wrap gap-4': layout === 'horizontal',
            // 内联布局 - 字段在同一行内排列，适合搜索表单
            'flex items-center gap-2': layout === 'inline',
          },
          className // 外部传入的自定义样式
        )}
      >
        {children}
      </form>
    </FormProvider>
  )
})

/**
 * Form 组件的设计器行为定义
 * 
 * 定义了该组件在 Formily Designable 设计器中的行为特性：
 * 1. 拖拽能力 - 是否可以被拖拽
 * 2. 克隆能力 - 是否可以被复制
 * 3. 删除能力 - 是否可以被删除
 * 4. 容器能力 - 是否可以接受其他组件拖入
 * 5. 属性配置 - 在属性面板中可配置的属性
 * 6. 默认属性 - 组件的默认配置
 */
Form.Behavior = createBehavior({
  name: 'Form', // 组件名称标识
  selector: (node) => node.componentName === 'Form', // 节点选择器
  designerProps(node) {
    return {
      // 拖拽能力 - 根节点不可拖拽，子节点可拖拽
      draggable: !node.isRoot,
      // 克隆能力 - 根节点不可克隆，子节点可克隆
      cloneable: !node.isRoot,
      // 删除能力 - 根节点不可删除，子节点可删除
      deletable: !node.isRoot,
      // 容器能力 - 表单组件可以接受其他组件作为子元素
      droppable: true,
      // 属性配置面板的 Schema 定义
      propsSchema: {
        type: 'object',
        properties: {
          // 布局模式选择器
          layout: {
            type: 'string',
            enum: ['vertical', 'horizontal', 'inline'], // 可选值
            'x-decorator': 'FormItem', // 使用 FormItem 装饰器
            'x-component': 'Select', // 使用下拉选择组件
            'x-component-props': {
              defaultValue: 'vertical', // 默认值
            },
          },
          // 继承通用的 CSS 样式配置
          ...AllSchemas.CSSStyle.properties,
        },
      },
      // 默认属性配置
      defaultProps: {
        layout: 'vertical', // 默认使用垂直布局
      },
    }
  },
  // 国际化文本配置
  designerLocales: AllLocales.Form,
})

/**
 * Form 组件的资源定义
 * 
 * 定义了该组件在设计器组件面板中的显示信息：
 * 1. 分类归属 - 属于 'Inputs' 分类
 * 2. 显示标题 - 支持多语言
 * 3. 图标标识 - 使用 FormLayoutSource 图标
 * 4. 默认元素 - 拖拽到画布时创建的默认结构
 */
Form.Resource = createResource('Inputs', {
  title: { 'zh-CN': '表单', 'en-US': 'Form' }, // 多语言标题
  icon: 'FormLayoutSource', // 组件图标
  elements: [
    {
      componentName: 'Field', // 创建 Field 节点
      props: {
        type: 'object', // 对象类型
        'x-component': 'Form', // 使用 Form 组件渲染
      },
    },
  ],
})